'use strict';
/**
 * author：小小游 --- allen
 * date：2018.02.07
 * lastUpdateDate：2018.02.07
 * description：Javascript中遍历对象属性的方式
 */
/**
 * 1.class B {}类里面定义的属性本身也算是可枚举属性
 * 2.可枚举属性：就类似我们同样定义了一个class B {}，在B类上加了一个原型
 * 方法，如B.prototype.getFullName = function () {};，那么注意这
 * 个方法就是可枚举的，Symbol['myName']() {}也是一个可枚举的
 * 3.不可枚举属性：就类似我们定义了一个class B {}，它里面有一个方法叫
 * getName () {}，那么注意这个方法就是不可枚举的
 */
class A {
    // 不可枚举的
    constructor () {
        this.name = 'xiaoxiaoyou';
    }

    // 不可枚举的
    getName () {

    }
}

class B extends A {
    // 不可枚举的
    constructor () {
        super ();
        this.age = 28;
        this.gender = '男';
    }

    // 不可枚举的
    getAge () {

    }

    // 可枚举的
    [Symbol('fullName')] () {

    }
}

// 可枚举的
B.prototype.getMySonAge = function () {

};

let b = new B ();
/**
 * 1.Object.keys()方法能够得到自身的可枚举属性，但得不到原型链上的属性
 * 2.Object.keys()方法也得不到Symbol属性
 */
// result：[ 'name', 'age' ]
console.log(Object.keys(b));
// result：[]
console.log(Object.keys(B.prototype));

console.log('-----------------**************---------------------');

/**
 * 1.Object.getOwnPropertyNames()方法能够得到自身的属性(包括不可枚举的属性)，
 * 但得不到原型链上的属性
 * 2.Object.getOwnPropertyNames()也得不到Symbol属性
 */
// result：[ 'name', 'age' ]
console.log(Object.getOwnPropertyNames(b));
// result：[ 'constructor', 'getAge' ]
console.log(Object.getOwnPropertyNames(B.prototype));

console.log('-----------------**************---------------------');

/**
 * Object.getOwnPropertySymbols()方法可以得到自身的Symbol属性，包括
 * 不可枚举的属性
 */
// result: []
// console.log(Object.getOwnPropertySymbols(b));
// result: [ Symbol(fullName) ]
console.log(Object.getOwnPropertySymbols(B.prototype));

console.log('-----------------**************---------------------');

// 这种方式是可以得到自身和继承自原型链上的属性，但必须是可枚举的属性
for (let k in b) console.log(k);

console.log('-----------------**************---------------------');

/**
 * 我们可以通过Object.getOwnPropertyDescriptor(B.prototype, 'getMySonAge')
 * 方法来检测当前的方法是否支持可枚举类型，如果enumerable : true表示支持可枚举属性
 * 反之，则不支持可枚举属性
 */
// result：可枚举的
/**
 * result：{ value : [ Function ],
 *           writable : true,
 *           enumerable : true,
 *           configurable : true
 *         }
 */
console.log(Object.getOwnPropertyDescriptor(B.prototype, 'getMySonAge'));

console.log('-----------------**************---------------------');
/**
 * result：{ value : [ Function : getAge ],
 *           writable : true,
 *           enumerable : false,
 *           configurable : true
 *         }
 */
// result：不可枚举的
console.log(Object.getOwnPropertyDescriptor(B.prototype, 'getAge'));
